/*
 * Copyright (c) 2011-2012 Alexander Dubu
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * o  Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * o  Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * o  Neither the name Axil nor the names of its contributors may be used to
 *    endorse or promote products derived from this software without specific
 *    prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
package axil.api.access;

import java.lang.annotation.*;


/**
 * An annotation for declaring a type accessible. To provide a safe scripting
 * environment, only objects explicitly declared as accessible can be accessed
 * by an Axil script. This annotation is placed on classes, abstract classes and
 * interfaces for host application objects. For example:
 * <pre>
 *     &#64;AccessibleType
 *     public class ShoppingCart
 *     {
 *         ...
 *     }
 * </pre>
 * By declaring the type accessible, Axil object are able to interact with this
 * object. By default, an accessible type only allows access to fields that are
 * explicitly declared as accessible. As a convenience, the PUBLIC and ANY
 * mechanisms are also provided.
 * </p>
 * If the hosting application object cannot annotate fields (as would be the
 * case for an object that stores data in a hash map within the object), then
 * the class may implement the Accessible interface to allow access to this type
 * of data as Axil objects.
 * <p/>
 * Finally, it may not be practical or possible to implement an interface or to
 * add annotations. For example, providing Axil access to the closed-source
 * third-party library means that the source cannot be changed. In this case,
 * Axil provides the Axil.access() method in the main API class for manually
 * installing a type adapter.
 *
 * @see Accessible
 * @see axil.api.Axil#access(Class, FieldDefinition...)
 */
@Retention(RetentionPolicy.RUNTIME)
@Target( {ElementType.TYPE })
@Inherited
public @interface AccessibleType {
	/**
	 * This enumerated type specifies the discovery mechanism used when a host
	 * application object is encountered.
	 */
	public enum Mechanism {
		/**
		 * Automatically add every method discovered that follows Java Bean-style
		 * programming conventions. That is, any public getX() or isX() method
		 * will be detected.
		 */
		PUBLIC,

		/**
		 * Automatically add any non-transient field discovered in the object.
		 * This includes any fields that are public, private or protected.
		 */
		ANY,

		/**
		 * Add only the fields that are explicitly specified via the
		 * &#64;AccessibleField annotation on a field or method. All others will
		 * be ignored. For security reasons, this is the default.
		 */
		EXPLICIT
	}

	/**
	 * Specify the mechanism by which accessible parts of a class or interface
	 * are detected. For security reasons, EXPLICIT is the default.
	 *
	 * @return
	 * 	Returns the discovery method.
	 */
Mechanism mechanism() default Mechanism.EXPLICIT;
}
